#ifdef TWE_DEBUG
#include <network_prober/logger/debug_logger.h>
#else
#include <network_prober/logger/release_logger.h>
#endif

#include <sys/mman.h>

#include <tcmalloc/malloc_extension.h>

#include <network_prober/sys_config/sys_config.h>
#include <network_prober/database/memory_db_holder.h>
#include <network_prober/database/file_db_holder.h>
#include <network_prober/rpc/perception_rpc_client.h>
#include <network_prober/probe/probe_task_handler.h>
#include <network_prober/backup/backup_task_handler.h>


int main(int argc, char *argv[])
{
    // 使用mlock防止swap
    // mlockall(mlockall(MCL_CURRENT | MCL_FUTURE));

    // 控制 TCMalloc 将未使用的内存归还给操作系统的频率。默认值为 1.0，表示 TCMalloc 会积极地将未使用的内存归还给操作系统。若将其设置为 0，则 TCMalloc 不会主动归还内存，适用于内存使用量波动较大的程序
    MallocExtension::instance()->SetMemoryReleaseRate(1.0); // 调整内存释放率

    // 初始化日志框架
#ifdef TWE_DEBUG
    // 开发模式
    network_prober::logger::DebugLogger::getInstance().init();
#else
    // 发布模式
    network_prober::logger::ReleaseLogger::getInstance().init();
#endif

    SPDLOG_INFO("正在初始化系统配置..");
    try {
        network_prober::sys_config::SysConfig::getInstance().init();
    } catch (const std::exception &e) {
        SPDLOG_ERROR("系统配置初始化错误：{}", e.what());
        return -1;
    }
    SPDLOG_INFO("系统配置初始化完成..");

    SPDLOG_INFO("正在初始化数据库..");
    try {
        // 初始化文件数据库
        network_prober::database::FileDBHolder::getInstance().init();
        // 初始化内存数据库
        network_prober::database::MemoryDBHolder::getInstance().init();
    } catch (const std::exception &e) {
        SPDLOG_ERROR("数据库初始化错误：{}", e.what());
        return -1;
    }
    SPDLOG_INFO("数据库初始化完成..");

    SPDLOG_INFO("正在启动设备观测线程..");
    std::jthread probeTaskHandlerThread([&] {
        try {
            network_prober::probe::ProbeTaskHandler::getInstance().start();
        } catch (const std::exception &e) {
            SPDLOG_ERROR("设备观测线程运行 错误：{}", e.what());
        }
    });

    SPDLOG_INFO("正在启动设备备份线程..");
    std::jthread backupTaskHandlerThread([&] {
        try {
            network_prober::backup::BackupTaskHandler::getInstance().start();
        } catch (const std::exception &e) {
            SPDLOG_ERROR("设备备份线程运行 错误：{}", e.what());
        }
    });

    SPDLOG_INFO("正在注册探针 rpc ...");
    std::jthread proberRPCClientThread([&] {
        try {
            network_prober::rpc::PerceptionRPCClient::getInstance().registerProber();
        } catch (const std::exception &e) {
            SPDLOG_ERROR("探针注册失败：{}", e.what());
        }
    });

    return 0;
}
